#!/usr/bin/env python
import PyQt4.QtGui
import PyQt4.Qwt5 as Qwt
from guiqwt.plot import CurveDialog
from guiqwt.builder import make
from PyQt4 import QtGui, QtCore
from Ui_MainForm import Ui_MainWindow
import sys
from scipy import linspace,arange,fft
from guiqwt.tools import HRangeTool
from guiqwt.builder import make
import numpy as np
from datetime import date
import  os
import string
import sys
from PyQt4 import QtGui, QtCore
from Ui_MainForm import Ui_MainWindow
from moddt8837 import  *
import threading


class save2disk(threading.Thread):
    def __init__(self, ideb, ifin, sizeblock):
        threading.Thread.__init__(self)
        self.ideb=ideb
        self.ifin=ifin
        self.sizeblock=sizeblock

    def run(self):    
        """ procedure de sauvegarded sur disque """
        """ entre un index de debut et un index de fin  """
        nbblock=int((self.ifin-self.ideb+1)/self.sizeblock)
        reste = (self.ifin - self.ideb+1)-nbblock*self.sizeblock
        for k in xrange(nbblock-1):
            i0=self.sizeblock*k+self.ideb
            i1=i0+self.sizeblock-1
            mess=":AD:FETCH? "+str(i0)+","+str(self.sizeblock)+"\n"
            err1=w.h1.write (mess)
            w.data=w.h1.read_raw()
            w.sizeHeader,w.sizeBuffer,w.header,w.buf =  readHeader(w.data)
        i0=i0+1
        i1=i0+reste-1
        mess=":AD:FETCH? "+str(i0)+","+str(reste)+"\n"
        err1=w.h1.write (mess)
        w.data=w.h1.read_raw()
        w.sizeHeader,w.sizeBuffer,w.header,w.buf =  readHeader(w.data)     
    def stop(self):
        self.Terminated = True
    

# creation de la classe acqui en derivant QThread
class Acqui(QtCore.QThread):
    "initialisation u thread affichage"
    def __init__(self):
        "initialisation du thread"
        QtCore.QThread.__init__(self)  # initialisation du thread

    def run(self):
        "programme principal du thread, excecution"
        w.listinfo.addItem("okkkkkkkkk")
        w.finish = False
        w.savedone1=0
        w.savedone2=1
        w.i0=0
        while (~w.finish):
            w.ADstatus, w.ideb, w.ifin=GetAdBufferStatus(w.h1)
            index = (w.ifin % 524032)
#            w.listinfo.addItem("info "+str(w.ADstatus)+" "+str(w.ideb % 524032)+" "+str(w.ifin % 524032))
            w.listinfo.addItem("info "+str(w.ADstatus)+" "+str(w.ideb)+" "+str(w.ifin))
            w.i1=w.ifin
            if w.i1>0:
                w.listinfo.addItem(str(w.i0)+" " +str(w.i1)+"  "+str(w.i1-w.i0))
                w.listinfo.scrollToBottom()
                Tsave.start(w.i0, w.i1, w.NB)
                w.i0=w.i1+1
            if (w.ADstatus==12):
                break
            time.sleep(0.5)

        w.finish=True

# creation de la classe lecture
class Lecture(QtCore.QThread):
    "initialisation u thread affichage"
    def __init__(self):
        "initialisation du thread"
        QtCore.QThread.__init__(self)  # initialisation du thread

    def run(self):
        "programme de lecture des donnees"
        N=200 #254  # work well only with 100 !!!!!!!!!!!!!!!!! or less than 255 (254)
        mess=":AD:FETCH? 0,"+str(N-1)+"\n"
        err1=w.h1.write (mess)
        w.data=w.h1.read_raw()
        w.sizeHeader,w.sizeBuffer,w.header,w.buf =  readHeader(w.data)
        w.listinfo.addItem( "header size : "+str(w.sizeHeader))
        w.listinfo.addItem( "buffer size : "+str(w.sizeBuffer))
        w.listinfo.addItem( "Size data header : "+str(w.header.shape)+ "  - " +str(w.header))
        w.flag=False
        i=1
        while (~w.flag):
            mess=":AD:FETCH? "+str(i*N) +","+str(N)+"\n"
            err1=w.h1.write (mess)
            w.data1=w.h1.read_raw()
            w.sizeHeader,w.sizeBuffer,w.header,w.buf1 =  readHeader(w.data1)
            w.xplot_data(w.buf1,w.nbchannel,w.sizeBuffer,w.fs)
            w.listinfo.addItem( "header size : "+str(w.sizeHeader))
            w.listinfo.addItem( "buffer size : "+str(w.sizeBuffer))
            w.listinfo.addItem( "Size data header : "+str(w.header.shape)+ "  - " +str(w.header))   
            w.listinfo.scrollToBottom()
            i +=1
            time.sleep(0.2)
        w.flag=True
        
class Ttest(threading.Thread):
    def __init__(self, m, n):
        threading.Thread.__init__(self)
        self.m=m
        self.n=n
       
        self.Terminated = False
    def run(self):
        print self.i, self.N
        mess=":AD:FETCH? "+str(self.i*self.N) +","+str(self.N)+"\n"
        err1=h1.write (mess)
        data1=h1.read_raw()
        sizeHeader,sizeBuffer,header,buf1 =  readHeader(data1)
        #
        self.buf=np.concatenate(( self.buf,buf1), axis=0)
        self.i += 1
    def stop(self):
        self.Terminated = True



class MonAppli(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)

        # user interface.
        self.setupUi(self)
        self.DEV1 = "TCPIP::169.254.241.13::INSTR"
        self.h1=0    # handle device dt8837
        self.level=1 # level  1 (1/10V) input
        self.fs=10000 # sampling rate
        self.dt = 1.0/self.fs # period
        self.data = []
        self.sizeHeader =0
        self.sizeBuffer=0
        self.header=[]
        self.buf=[]
        self.flagOneInstanceSignal=0 #pour affichage , initialisation puis update
        self.win_signal=None   # initialise fenetre signal
        self.nbchannel=4   # 4 channel by DT
        self.NB=254  # taille bloc de lecture max=254
        self.NBI = 0 # index initial pour fetch
        self.NBF = 0 # index fin bloc pour fetch
        self.index = 0 # index de boucle de fetch
        self.i0 = 0
        self.i1 = 0
  
#--------------------------------------------------------------------
# menus
#--------------------------------------------------------------------
  
#--------------------------------------------------------------------
# boutons
#--------------------------------------------------------------------
        self.connect(self.pushButtonConnect,QtCore.SIGNAL("clicked()"),On_pushButtonConnect)
        self.connect(self.pushButtonDeconnect,QtCore.SIGNAL("clicked()"),On_pushButtonDeconnect)
  
  
#--------------------------------------------------------------------
# lineEdit
#--------------------------------------------------------------------
#--------------------------------------------------------------------
# fonctions des menus 
#--------------------------------------------------------------------
#--------------------------------------------------------------------
# fonctions des boutons   
#--------------------------------------------------------------------


    def xplot_data(self,buf,nbvoie,nbpoint,fs):
        " affiche les voies acquisition"
        t=[]    # initiale temps
        dt=1.0/fs   # periode des signaux
        t=linspace(0,(nbpoint-1)*dt,nbpoint) # axe des temps
        if w.flagOneInstanceSignal==0:   # premier passage initialise fenetre
            w.win_signal = CurveDialog(edit=False, toolbar=True, wintitle="Temporal signal",
                          options=dict(title="Signal", xlabel="Temps",
                                       ylabel="Amplitude"))
            w.win_signal.add_tool(HRangeTool)   # barre outils selection zone
            p1 = w.win_signal.get_plot()        # initialise le plot
            for i in range(nbvoie):
               ## y=buf[i][0:nbpoint] # recup voie
                y=buf[i::4]
                mess="w.curve"+str(i)+"=make.curve(t, y, color=\"b\",title=\"voie "+str(i)+"\")" # intitialise la courne
                exec(mess)
                mess="p1.add_item(w.curve"+str(i)+")"  # ajoute la courbe au plot
                exec(mess)
            w.win_signal.get_itemlist_panel().show()
            #p1.set_items_readonly(False)
            w.flagOneInstanceSignal=1       # flip flop
        if w.flagOneInstanceSignal==1:      # second passage
            for i in range(nbvoie):
                ##y=buf[i][0:nbpoint]         # recup voies
                y=buf[i::4]
                mess="w.curve"+str(i)+".set_data(t, y)" # on met a jour uniquement les donnees
                exec(mess)
                mess="w.curve"+str(i)+".plot().replot()" # et on re plot
                exec(mess)
        w.win_signal.show()   # affiche figure
        w.win_signal_exist = True
        return


def On_pushButtonConnect():
    w.h1 = getHandle(w.DEV1)
    mess=getID(w.h1)
    w.listinfo.addItem("Device name : "+mess)
    w.listinfo.addItem(" Enable AD for all channel")
    doRST(w.h1)
    err1 = setAdEnableAll(w.h1)    
    w.listinfo.addItem("Channel coupling AC ...")
    err1 = setCouplage(w.h1,'AC')
    w.listinfo.addItem("Init level ...")
    w.level=1   # 1V en entree 1 ou 10
    err1 = setGain(w.h1,w.level)
    w.listinfo.addItem("Mode  buffer wrap/no wrap ...")
    err1 = setWrap(w.h1,"off")  #   buffer circulaire
    w.h1.write("ad:buffer:size?")
    mess = w.h1.read()
    w.listinfo.addItem("Buffer size : "+mess)
    w.listinfo.addItem("Initialisation horloge interne ...")
    err1=setADClockInternal(w.h1)
    w.listinfo.addItem("Initialisation frequence horloge interne ...")
    w.fs= 5000 # Hz
    err1=setFreqClock(w.h1,w.fs)
    w.dt=1.0/w.fs    #periode echantillonnange
    w.listinfo.addItem("Sampling rate : "+str(w.fs)+" hz")
    w.listinfo.addItem("Init source trigger immediat ...")
    err1=setAdTrigSourceImm(w.h1)
    
    w.ADstatus, w.ideb, w.ifin=GetAdBufferStatus(w.h1)
    w.listinfo.addItem("avant armement "+str(w.ADstatus)+" "+str(w.ideb)+" "+str(w.ifin)+" delta ="+str(w.ifin-w.ideb+1))

    
    
    w.listinfo.addItem( "Armement des mesures, pret a lancer ...")
    err1=setAdArm(w.h1)

    w.ADstatus, w.ideb, w.ifin=GetAdBufferStatus(w.h1)
    w.listinfo.addItem("apres armement "+str(w.ADstatus)+" "+str(w.ideb)+" "+str(w.ifin)+" delta ="+str(w.ifin-w.ideb+1))

    
    w.listinfo.addItem("lance la mesure ....")
    err1=setAdInit(w.h1)       
   
    w.ADstatus, w.ideb, w.ifin=GetAdBufferStatus(w.h1)
    w.listinfo.addItem("mesure lancee "+str(w.ADstatus)+" "+str(w.ideb)+" "+str(w.ifin)+" delta ="+str(w.ifin-w.ideb+1))

  
    w.listinfo.scrollToBottom()  
    ThreadAcq.start()

#
#    w.finish=True
#    time.sleep(2)
##    ThreadLect.terminate()
#    ThreadAcq.terminate()
#    err1=setAdStop(w.h1)        
#    ThreadLect.start()
    return
  
def On_pushButtonDeconnect():
    w.flag=True
    w.finish=True
#    ThreadLect.terminate()
    ThreadAcq.terminate()
    err1=setAdStop(w.h1)
#    N=200 #254  # work well only with 100 !!!!!!!!!!!!!!!!! or less than 255 (254)
#    mess=":AD:FETCH? 0,"+str(N-1)+"\n"
#    err1=w.h1.write (mess)
#    w.data=w.h1.read_raw()
#    err1=w.h1.write("AD:STATus:SCAN?")
#    rep=w.h1.read()
#    w.listinfo.addItem("index : "+rep)
#    w.sizeHeader,w.sizeBuffer,w.header,w.buf =  readHeader(w.data)
#    w.listinfo.addItem( "header size : "+str(w.sizeHeader))
#    w.listinfo.addItem( "buffer size : "+str(w.sizeBuffer))
#    w.listinfo.addItem( "Size data header : "+str(w.header.shape)+ "  - " +str(w.header))
#    w.listinfo.scrollToBottom()
#    w.nbchannel=4
#    w.xplot_data(w.buf,w.nbchannel,w.sizeBuffer,w.fs)
#    for i in range(1,100):
#        mess=":AD:FETCH? "+str(i*N) +","+str(N)+"\n"
#        err1=w.h1.write (mess)
#        w.data1=w.h1.read_raw()
#        w.sizeHeader,w.sizeBuffer,w.header,w.buf1 =  readHeader(w.data1)
#        w.xplot_data(w.buf1,w.nbchannel,w.sizeBuffer,w.fs)
#        w.listinfo.addItem( "header size : "+str(w.sizeHeader))
#        w.listinfo.addItem( "buffer size : "+str(w.sizeBuffer))
#        w.listinfo.addItem( "Size data header : "+str(w.header.shape)+ "  - " +str(w.header))        
#        w.buf=np.concatenate(( w.buf,w.buf1), axis=0)    
#        
#        w.listinfo.scrollToBottom()
        
    return
  
#--------------------------------------------------------------------
# fonctions des LineEdit    
#--------------------------------------------------------------------
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    w = MonAppli()
    ThreadAcq = Acqui()
    Tsave = save2disk(None, None, None)
#    ThreadLect = Lecture()
    w.show()
    sys.exit(app.exec_())
    
    #            if (index>262016 and index<524032):
#                if (w.savedone1==0) :
#                   w.listinfo.addItem("----------------")
#                   w.listinfo.addItem("sauve buffer 1 de 0 a N2")
#                   w.listinfo.addItem("----------------")
#                   save2disk(0, 262016, w.NB)
#                   w.listinfo.scrollToBottom()
#                   w.savedone1=1
#                   w.savedone2=0
#                   
#            if (index >0  and index<262016):
#                if (w.savedone2==0):
#                   w.listinfo.addItem("----------------")
#                   w.listinfo.addItem("sauve buffer 2 de N2 a N")
#                   w.listinfo.addItem("----------------")
#                   save2disk(262016,524032 , w.NB)
#                   w.listinfo.scrollToBottom()
#                   w.savedone1=0
#                   w.savedone2=1    
